<template>
  <!-- 最外层视口 -->
  <div
    class="viewport"
    @scroll="handleScroll"
    :style="{ height: `${props.size * props.remain}px` }"
  >
    <!-- 滚动条 -->
    <div
      class="scroll-bar"
      :style="{ height: `${props.size * props.items.length}px` }"
    ></div>
    <!-- 内容 -->
    <div class="scroll-list" :style="{ transform: `translateY(${offset}px)` }">
      <div v-for="item in viewData" :key="item.id" :vid="item.id">
        <slot :item="item"></slot>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";
const props = defineProps({
  //每个元素的定高 px
  size: {
    type: Number,
    default: 0,
  },
  //可视区域要显示几个元素
  remain: {
    type: Number,
    default: 0,
  },
  items: {
    type: Array,
    default: () => [],
  },
});
let start = ref(0);
let end = ref(props.remain);
let offset = ref(0);

//前面预留几个 如果start是0 代表前面没有 也就是前面不用预留
let prevCount = computed(() => {
  return Math.min(start.value, props.remain);
});
//后面一页预留几个 的临界值 最后一页剩3个元素 但是每页要显示8个 就用剩下的
let nextCount = computed(() => {
  return Math.min(props.items.length - end.value, props.remain);
});

let viewData = computed(() => {
  let startVal = start.value - prevCount.value;
  let endVal = end.value + nextCount.value;
  console.log(startVal, endVal);

  return props.items.slice(startVal, endVal);
});

//处理滚动
function handleScroll(e) {
  let scrollTop = e.target.scrollTop;
  console.log(scrollTop);
  //向下取整 滚动了几个元素
  start.value = Math.floor(scrollTop / props.size);
  end.value = start.value + props.remain;
  //因为list是相对定位  会被滚上去 所以设置 处理偏移量 让start元素向下来  但是因为有默认的前一页，所以需要把前一页的偏移量减去 相当于是以start为基准
  offset.value = (start.value - prevCount.value) * props.size;
}
</script>

<style scoped>
.viewport {
  width: 100%;
  position: relative;
  overflow-y: scroll;
}
.scroll-bar {
  /* overflow-y: scroll; */
}

.scroll-list {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}
</style>
